#ifndef __MSTTASK_H_
#define __MSTTASK_H_

#include <iostream>
#include <defs.h>
#include <vector>
#include <map>
#include <queue>
#include <TFrame.h>
#include <pthread.h>
#include <sys/time.h>

// class that holds the MST task 
class MSTTask_t : public Task{
 private:
  Graph_t * graph; //!< pointer to main graph
  WorkQueue * Q; //!< pointer to task queue
  bool * changed; //!< boolean pointer to state of T - E
  bool initial; //!< Indicates whether first time in run method
  int count; //!< count of active children
  std::map <edge_descriptor_t, int> * e_map; //!< pointer to map of edges in the tree
  std::map <int, int> * v_map; //!< pointer to map of vertices in the tree
  std::map <vertex_iterator_t, vertex_iterator_t> * who_map; //!< pointer to map of vertices parents in the tree
  std::queue <vertex_iterator_t> * v_queue; //!< pointer to queue of yet to visit vertices
  pthread_mutex_t qmutex; //!< mutex on queue
  pthread_mutex_t cmutex; //!< mutex on count
  pthread_mutex_t emutex; //!< mutex on map of edges
  pthread_mutex_t vmutex; //!< mutex on map of vertices 
  pthread_mutex_t who_mutex; //!< mutex on who map 
  timeval tim;
  double t1, t2;
  
 public:
  /**
   * \brief Default constructor
   */
  MSTTask_t();

  /**
   * \brief Constructor
   */
  MSTTask_t(Graph_t *,  //!< Pointer to input graph
	    WorkQueue * //!< Pointer to input queue of tasks
	    );

  /**
   * \brief Destructor
   */
  ~MSTTask_t();

  /**
   * \brief run method containing main implementation
   */
  virtual void run();
};

class MergeTask_t : public Task {
 private:
  Graph_t * graph; //!< pointer to main graph
  vertex_iterator_t vit; //!< vertex iterator for the input
  int * count; //!< count of tasks

  std::map <edge_descriptor_t, int> * e_map; //!< pointer to map of edges in the tree
  std::map <int, int> * v_map; //!< pointer to map of vertices in the tree
  std::map <vertex_iterator_t, vertex_iterator_t> * who_map; //!< pointer to map of vertices parents in the tree
  std::queue <vertex_iterator_t> * v_queue; //!< pointer to queue of yet to visit vertices

  pthread_mutex_t * qmutex; //!< mutex on queue
  pthread_mutex_t * cmutex; //!< mutex on count
  pthread_mutex_t * emutex; //!< mutex on map of edges
  pthread_mutex_t * vmutex; //!< mutex on map of vertices 
  pthread_mutex_t * who_mutex; //!< mutex on who map 

 public:
  /**
   * \brief Default constructor
   */
  MergeTask_t();
  
  /**
   * \brief Constructor
   */
  MergeTask_t(Graph_t *,                                        //!< input graph
	      vertex_iterator_t,                                //!< input vertex iterator
	      int *,                                            //!< input active task count
	      std::map<edge_descriptor_t, int> *,               //!< input edge map
	      std::map<int, int> *,                             //!< input vertex map
	      std::map<vertex_iterator_t, vertex_iterator_t> *, //!< input parent map
	      std::queue<vertex_iterator_t> *,                  //!< input vertex queue
	      pthread_mutex_t *,                                //!< input queue mutex
	      pthread_mutex_t *,                                //!< input count mutex
	      pthread_mutex_t *,                                //!< input edge mutex
	      pthread_mutex_t *,                                //!< input vertex mutex
	      pthread_mutex_t *                                 //!< input who mutex
	      );
  
  /**
   * \brief Destructor
   */
  ~MergeTask_t();
  
  /**
   * \brief Run method
   */
  virtual void run();
};

#endif
